Function Selector
概要
EVMで、実行する関数を一意に特定するときの関数のIDの付け方のお話
仕様
https://solidity.readthedocs.io/en/v0.4.21/abi-spec.html#function-selector
function idはfunction signatureをsha3でハッシュ化した最初の4byte
function signatureは、function nameの後にそのfunctionのparameter typesを(スペースを入れずに)カンマで区切って括弧を付けたもの
例
https://github.com/OpenZeppelin/openzeppelin-solidity/blob/83bc045a56d891726ab3a4cbdd6be35e0023e72c/contracts/token/ERC721/IERC721Receiver.sol#L21
code: function id of onERC721Received
bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))
web3でfunction signatureを計算するとき
https://web3js.readthedocs.io/en/1.0/web3-eth-abi.html#encodefunctionsignature
code: encodeFunctionSignature
// From a JSON interface object
web3.eth.abi.encodeFunctionSignature({
name: 'myMethod',
type: 'function',
inputs: [{
type: 'uint256',
name: 'myNumber'
},{
type: 'string',
name: 'myString'
}]
})
0x24ee0097
// Or string
web3.eth.abi.encodeFunctionSignature('myMethod(uint256,string)')
'0x24ee0097'
実装
Solidity
https://github.com/ethereum/solidity/blob/b14eec5babb416edf49aa15d6b4765dd579da823/libsolidity/ast/Types.cpp
各クラスの canonicalName
Vyper
https://github.com/ethereum/vyper/blob/0fa67d0268958558b6b477cff79c530b2ae22913/vyper/types/types.py#L159
def canonicalize_type
yudetamago.icon > 見た感じVyperのfunction idの実装は、TypeNameについてはSolidityと互換性がありそう
VyperとSolidityのコンパイル時の違い
Vyper
calldataの先頭32bytesはメモリの28~59のところに格納
メモリの0~27は0、よって、メモリの先頭32バイトが、左側を0で埋められた32バイトの関数シグネチャになる
Solidity
calldataの先頭32bytesはまずスタックに入る
そして、2^(28*8)で割り算(28バイト右シフト)
リンク
https://solidity.readthedocs.io/en/v0.4.25/abi-spec.html#function-selector
https://y-nakajo.hatenablog.com/entry/2018/09/16/154612
#Solidity #Vyper